<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.3.0: http://docutils.sourceforge.net/" />
<title>vb2Py - Functions</title>
<link rel="stylesheet" href="default.css" type="text/css" />
</head>
<body>
<div class="document" id="vb2py-functions">
<h1 class="title">vb2Py - Functions</h1>
<!-- filename: c:\development\python22\lib\site-packages\vb2py\doc/function.htm -->
<p>Contents of this page:</p>
<ul class="simple">
<li><a class="reference" href="#general">General</a></li>
<li><a class="reference" href="#default-conversion">Default Conversion</a></li>
<li><a class="reference" href="#list-of-options">List of Options</a></li>
</ul>
<p>Specific options:</p>
<ul class="simple">
<li><a class="reference" href="#returnvariablename">ReturnVariableName</a></li>
<li><a class="reference" href="#preinitializereturnvariable">PreInitializeReturnVariable</a></li>
</ul>
<p>Additional</p>
<ul class="simple">
<li><a class="reference" href="#missing-arguments">Missing Arguments</a></li>
<li><a class="reference" href="#argument-passing">Argument Passing</a></li>
</ul>
<div class="section" id="general">
<h1><a name="general">General</a></h1>
<p>Functions are converted to Python functions with an explicit return statement. By default, a return variable is created and initialize as soon as the function starts (in case the function exits before the variable is assigned a proper value). Assignments to the VB function name are mapped to the return variable.</p>
<p>Local variables in the VB functions are also local in the Python version. If a module global is used on the left hand side of an assignment then a Python <tt class="literal"><span class="pre">global</span></tt> statement will be inserted at the head of the function. Project <em>globals</em> will be replaced by their fully-qualified versions.</p>
</div>
<div class="section" id="default-conversion">
<h1><a name="default-conversion">Default Conversion</a></h1>
<table style="code-table"><tr><th class="code-header">VB</th><th class="code-header">Python</th></tr><tr><td class="vb-code-cell"><pre><br>Dim moduleGlobal1, moduleGlobal2<br><br>Function MyFunc(X, Optional Y, Optional Z=20)<br>    Dim subLocal<br>    subLocal = X + Y + Z + moduleGlobal<br>    moduleGlobal2 = moduleGlobal2 + 1<br>    MyFunc = subLocal*10<br>End Function<br><br>a = MyFunc(1, 2)<br>a = MyFunc(1, Z:=10)<br></pre></td><td class="python-code-cell"><pre><br><br><br>    moduleGlobal1 = Variant()<br>    moduleGlobal2 = Variant()<br><br>    def MyFunc(X, Y=VBMissingArgument, Z=20):<br>        global moduleGlobal2<br>        _ret = None<br>        subLocal = X + Y + Z + moduleGlobal<br>        moduleGlobal2 = moduleGlobal2 + 1<br>        _ret = subLocal * 10<br>        return _ret<br><br>    a = MyFunc(1, 2)<br>    a = MyFunc(1, Z= 10)<br></pre></td></tr></table>
<div class="section" id="missing-arguments">
<h2><a name="missing-arguments">Missing Arguments</a></h2>
<p>Optional arguments which are not supplied and have no defaults are initialized with the <tt class="literal"><span class="pre">VBMissingArgument</span></tt> object. This object can be detected by the <tt class="literal"><span class="pre">vbfunctions.IsMissing</span></tt> function to provide initialization of missing arguments within the body of the function. This functionality is transparent under normal conditions, but if the function manually assigns a value to the missing parameter prior to the IsMissing call then the behaviour may not match that of VB, since the <tt class="literal"><span class="pre">vbfunctions.IsMissing</span></tt> function has no way to detect that the parameter was not supplied.</p>
<table style="code-table"><tr><th class="code-header">VB</th><th class="code-header">Python</th></tr><tr><td class="vb-code-cell"><pre><br>Dim moduleGlobal1, moduleGlobal2<br><br>Function MyFunc(X, Optional Y, Optional Z=20)<br>    Dim subLocal<br>    If IsMissing(Y) Then Y = 12<br>    subLocal = X + Y + Z + moduleGlobal<br>    moduleGlobal2 = moduleGlobal2 + 1<br>    MyFunc = subLocal*10<br>End Function<br><br>a = MyFunc(1, 2)<br>a = MyFunc(1, Z:=10)<br></pre></td><td class="python-code-cell"><pre><br><br><br>    moduleGlobal1 = Variant()<br>    moduleGlobal2 = Variant()<br><br>    def MyFunc(X, Y=VBMissingArgument, Z=20):<br>        global moduleGlobal2<br>        _ret = None<br>        if IsMissing(Y):<br>            Y = 12<br>        subLocal = X + Y + Z + moduleGlobal<br>        moduleGlobal2 = moduleGlobal2 + 1<br>        _ret = subLocal * 10<br>        return _ret<br><br>    a = MyFunc(1, 2)<br>    a = MyFunc(1, Z= 10)<br></pre></td></tr></table>
</div>
<div class="section" id="argument-passing">
<h2><a name="argument-passing">Argument Passing</a></h2>
<p>VB has two argument passing schemes,</p>
<ol class="arabic simple">
<li><tt class="literal"><span class="pre">ByRef</span></tt> (Default) - arguments are passed by reference. Changes to the value inside the
subroutine are reflected in the corresponding parameter in the calling scope.</li>
<li><tt class="literal"><span class="pre">ByVal</span></tt> - arguments are passed by value. Changes to the value inside the subroutine do
not affect the parameter in the calling scope.</li>
</ol>
<p>Although Python's argument passing semantics are often refered to as pass-by-reference, the actual behaviour does not always match VB's <tt class="literal"><span class="pre">ByRef</span></tt> because of immutable object types and name re-binding. Although there are technical solutions for these issues, the current version of vb2Py does not make any attempt to match behaviours.</p>
<p><strong>This means that the following code, although converted, does not behave the same in the Python version</strong></p>
<table style="code-table"><tr><th class="code-header">VB</th><th class="code-header">Python</th></tr><tr><td class="vb-code-cell"><pre><br>Sub DoIt(x, ByVal y)<br>    x = x + 1<br>    y = y + 1<br>End Sub<br><br>x = 0<br>y = 0<br>DoIt x, y<br>' x is now 1, y is still 0<br></pre></td><td class="python-code-cell"><pre><br><br><br><br>    def DoIt(x, y):<br>        x = x + 1<br>        y = y + 1<br><br>    x = 0<br>    y = 0<br>    DoIt(x, y)<br>    # x is now 1, y is still 0<br></pre></td></tr></table>
</div>
</div>
<div class="section" id="list-of-options">
<h1><a name="list-of-options">List of Options</a></h1>
<p>Here are the options in the INI file:</p>
<pre class="literal-block">
[Functions]
# Name of variable used in Functions
ReturnVariableName = _ret             
# Yes or No, leave at Yes unless good reasons!
PreInitializeReturnVariable = Yes     
</pre>
<div class="section" id="returnvariablename">
<h2><a name="returnvariablename">ReturnVariableName</a></h2>
<p>Syntax: <tt class="literal"><span class="pre">ReturnVariableName</span> <span class="pre">=</span> <span class="pre">name</span></tt></p>
<p>This option allows the return variable name to be specified. No checking is done to ensure that the name does not clash with local or global variables, so care should be taken when selecting a suitable name.</p>
<table style="code-table"><tr><th class="code-header">VB</th><th class="code-header">Python</th></tr><tr><td class="vb-code-cell"><pre><br>Dim moduleGlobal1, moduleGlobal2<br><br>' VB2PY-GlobalSet: Functions.ReturnVariableName = _MyFunc<br>Function MyFunc(X, Optional Y, Optional Z=20)<br>    Dim subLocal<br>    subLocal = X + Y + Z + moduleGlobal<br>    moduleGlobal2 = moduleGlobal2 + 1<br>    MyFunc = subLocal*10<br>End Function<br>' VB2PY-Unset: Functions.ReturnVariableName <br><br>a = MyFunc(1, 2)<br>a = MyFunc(1, Z:=10)<br></pre></td><td class="python-code-cell"><pre><br><br><br>    moduleGlobal1 = Variant()<br>    moduleGlobal2 = Variant()<br><br>    def MyFunc(X, Y=VBMissingArgument, Z=20):<br>        global moduleGlobal2<br>        _MyFunc = None<br>        subLocal = X + Y + Z + moduleGlobal<br>        moduleGlobal2 = moduleGlobal2 + 1<br>        _MyFunc = subLocal * 10<br>        return _MyFunc<br><br>    a = MyFunc(1, 2)<br>    a = MyFunc(1, Z= 10)<br></pre></td></tr></table>
</div>
<div class="section" id="preinitializereturnvariable">
<h2><a name="preinitializereturnvariable">PreInitializeReturnVariable</a></h2>
<p>Syntax: <tt class="literal"><span class="pre">PreInitializeReturnVariable</span> <span class="pre">=</span> <span class="pre">Yes</span> <span class="pre">|</span> <span class="pre">No</span></tt></p>
<p>By default the return variable is initialized to <tt class="literal"><span class="pre">None</span></tt> at the start of the function so that an error does not occur in the event that the function returns before the return variable has been assigned to. This option allows this initialization step to be omitted and is safe as long as all return paths from the function include an explicit assignment to the return value variable.</p>
<table style="code-table"><tr><th class="code-header">VB</th><th class="code-header">Python</th></tr><tr><td class="vb-code-cell"><pre><br>Dim moduleGlobal1, moduleGlobal2<br><br>' VB2PY-GlobalSet: Functions.PreInitializeReturnVariable = No<br>Function MyFunc(X, Optional Y, Optional Z=20)<br>    Dim subLocal<br>    subLocal = X + Y + Z + moduleGlobal<br>    moduleGlobal2 = moduleGlobal2 + 1<br>    MyFunc = subLocal*10<br>End Function<br>' VB2PY-Unset: Functions.PreInitializeReturnVariable <br><br>a = MyFunc(1, 2)<br>a = MyFunc(1, Z:=10)<br></pre></td><td class="python-code-cell"><pre><br><br><br>    moduleGlobal1 = Variant()<br>    moduleGlobal2 = Variant()<br><br>    def MyFunc(X, Y=VBMissingArgument, Z=20):<br>        global moduleGlobal2<br>        subLocal = X + Y + Z + moduleGlobal<br>        moduleGlobal2 = moduleGlobal2 + 1<br>        _ret = subLocal * 10<br>        return _ret<br><br>    a = MyFunc(1, 2)<br>    a = MyFunc(1, Z= 10)<br></pre></td></tr></table>
</div>
</div>
</div>
</body>
</html>
